home *** CD-ROM | disk | FTP | other *** search
/ Compendium Deluxe 1 / LSD Compendium Deluxe 1.iso / a / programming / assembly / kcx25asc.lha / KCX / PackRow.Asm < prev    next >
Encoding:
Assembly Source File  |  1993-06-21  |  7.5 KB  |  250 lines

  1. ****************************************************************
  2. *
  3. *  Copyright 1988 by CREATIVE FOCUS.  This code is freely
  4. *  distributable as long as this notice is retained and no
  5. *  other conditions are imposed upon its redistribution.
  6. *
  7. *
  8. *  APACK.ASM --
  9. *
  10. *  A fully compatible replacement for Electronic Arts' PACKER.C
  11. *  routine.  Converts data according to the IFF ILBM cmpByteRun1
  12. *  compression protocol:
  13. *
  14. *     control bytes:
  15. *
  16. *        n =  0.. 127:   followed by n+1 bytes of data;
  17. *        n = -1..-127:   followed by byte to be repeated -n+1 times;
  18. *        n =     -128:   don't do no nada.
  19. *
  20. *     calling format:
  21. *
  22. *        long packrow(from, too, amt)
  23. *           char **from, /* pointer to source data pointer */
  24. *                **too;  /* pointer to destination data pointer */
  25. *           long amt;    /* number of bytes to compress */
  26. *
  27. *        return(number of bytes written to destination);
  28. *
  29. *     effects: 
  30. *         *from = *from + amt, and *too = *too + return; 
  31. *         return is "smart," that is, not greater than 
  32. *         MaxPackedSize = amt + ((amt+127) >> 7).
  33. *     By commenting out CHECK (below) you disable checking for runs 
  34. *     exceeding 128 bytes.  That CHECK is not needed if you are sure 
  35. *     the amt to be compressed is always 128 or less. 
  36. *  !!! DISCLAIMER !!!  You use this code entirely at your own 
  37. *  risk.  I don't warrantee its fitness for any purpose.  I 
  38. *  can't even guarantee the accuracy of anything I've said 
  39. *  about it, though I've tried my damndest to get it right. 
  40. *  I may, in fact, be completely out of my tiny little mind :-). 
  41. *  That being said, I can be reached for questions, comments, 
  42. *  or concerns at: 
  43. *        Dr. Gerald Hull 
  44. *        CREATIVE FOCUS 
  45. *        12 White Street 
  46. *        Binghamton, N.Y.  13901 
  47. *        (607) 648-4082 
  48. *        bix:    ghull 
  49. *        PLink:  DRJERRY 
  50. *************************************************************** 
  51.  
  52.       xdef  _packrow 
  53.  
  54. PT    equr  a0                -> beginning of replicate run (if any) 
  55. IX    equr  a1                -> end+1 of input line 
  56. IP    equr  a2                -> beginning of literal run (if any) 
  57. IQ    equr  a3                -> end+1 of lit and/or rep run (if any) 
  58. OP    equr  a4                -> end+1 of output line current pos 
  59. FP    equr  a6                frame pointer 
  60. SP    equr  a7                stack pointer 
  61.  
  62. RET    equr  d0                return value
  63. MX    equr  d1                check for maximum run = MAX
  64. AM    equr  d2                amount
  65. CH    equr  d3                character
  66.  
  67. REGS  reg   AM/CH/IP/IQ/OP
  68.  
  69. FRM   equ   8                 input line address
  70. TOO   equ   12                output line address
  71. AMT   equ   16                length of input line
  72.  
  73. MAX   equ   128               maximum encodable output run
  74. * CHECK equ   1                 turns on maximum row checking
  75.  
  76.  
  77. _packrow
  78.  
  79.  
  80. ***************     CASE 0:   GRAB PARAMS & INITIALIZE 
  81. CAS0 
  82.       link     FP,#0 
  83.       movem.l  REGS,-(SP) 
  84.       movea.l  FRM(FP),IP 
  85.       movea.l  (IP),IP        IP = *from 
  86.       movea.l  IP,IQ          IQ = IP 
  87.       movea.l  IQ,IX 
  88.       adda.l   AMT(FP),IX     IX = IP + amt 
  89.       movea.l  TOO(FP),OP 
  90.       movea.l  (OP),OP        OP = *too 
  91.  
  92.  
  93. ***************     CASE 1:   LITERAL RUN 
  94. CAS1 
  95.       movea.l  IQ,PT          adjust PT (no replicates yet!) 
  96.       move.b   (IQ)+,CH       grab character 
  97.       cmpa.l   IQ,IX          if input is finished 
  98.       beq.s    CAS5              branch to case 5 
  99.  
  100.       ifd      CHECK 
  101.       move.l   IQ,MX 
  102.       sub.l    IP,MX 
  103.       cmpi     #MAX,MX        if run has reached MAX 
  104.       beq.s    CAS6              branch to case 6 
  105.       endc 
  106.  
  107.       cmp.b    (IQ),CH        if next character != CH 
  108.       bne.s    CAS1              stay in case 1 
  109.  
  110. *                             else fall into case 2 
  111.  
  112.  
  113. ***************     CASE 2:   AT LEAST 2 BYTE REPEAT 
  114. CAS2 
  115.       move.b   (IQ)+,CH       grab character 
  116.       cmpa.l   IQ,IX          if input is finished 
  117.       beq.s    CAS7              branch to case 7 
  118.  
  119.       ifd      CHECK 
  120.       move.l   IQ,MX 
  121.       sub.l    IP,MX 
  122.       cmpi     #MAX,MX        if run has reached MAX 
  123.       beq.s    CAS6              branch to case 6 
  124.       endc 
  125.  
  126.       cmp.b    (IQ),CH        if next character != CH 
  127.       bne.s    CAS1              branch to case 1 
  128.  
  129. *                             else fall into case 3 
  130.  
  131.  
  132. ***************     CASE 3:   REPLICATE RUN 
  133. CAS3
  134.       move.b   (IQ)+,CH       grab character 
  135.       cmpa.l   IQ,IX          if input is finished 
  136.       beq.s    CAS7              branch to case 7 
  137.  
  138.       ifd      CHECK 
  139.       move.l   IQ,MX 
  140.       sub.l    PT,MX 
  141.       cmpi     #MAX,MX        if run has reached MAX 
  142.       beq.s    CAS4              branch to case 4 
  143.       endc 
  144.  
  145.       cmp.b    (IQ),CH        if next character = CH 
  146.       beq.s    CAS3              stay in case 3 
  147.  
  148. *                             else fall into case 4 
  149.  
  150.  
  151. ***************     CASE 4:   LIT AND/OR REP DUMP & CONTINUE 
  152. CAS4 
  153.       move.l   PT,AM 
  154.       sub.l    IP,AM          AM = PT - IP 
  155. *                             if no literal run 
  156.       beq.s    C41               branch to replicate run 
  157.  
  158.       subq     #1,AM          AM = AM - 1 
  159.       move.b   AM,(OP)+       output literal control byte 
  160.  
  161. C40   move.b   (IP)+,(OP)+    output literal run 
  162.       dbra     AM,C40 
  163.  
  164. C41   move.l   PT,AM 
  165.       sub.l    IQ,AM          AM = PT - IQ (negative result!) 
  166.       addq     #1,AM          AM = AM + 1 
  167.       move.b   AM,(OP)+       output replicate control byte 
  168.       move.b   CH,(OP)+       output repeated character 
  169.       movea.l  IQ,IP          reset IP 
  170.       bra.s    CAS1           branch to case 1 (not done) 
  171.  
  172.  
  173. ***************     CASE 5:   LITERAL DUMP & QUIT 
  174. CAS5 
  175.       move.l   IQ,AM 
  176.       sub.l    IP,AM          AM = IQ - IP (positive result > 0) 
  177.       subq     #1,AM          AM = AM - 1 
  178.       move.b   AM,(OP)+       output literal control byte 
  179.  
  180. C50   move.b   (IP)+,(OP)+    output literal run 
  181.       dbra     AM,C50 
  182.  
  183.       bra.s    CAS8           branch to case 8 (done) 
  184.  
  185.  
  186.       ifd      CHECK 
  187.  
  188. ***************     CASE 6:   LITERAL DUMP & CONTINUE 
  189. CAS6
  190.       move.l   IQ,AM 
  191.       sub.l    IP,AM          AM = IQ - IP (positive result > 0) 
  192.       subq     #1,AM          AM = AM - 1 
  193.       move.b   AM,(OP)+       output literal control byte 
  194.  
  195. C60   move.b   (IP)+,(OP)+    output literal run 
  196.       dbra     AM,C60 
  197.  
  198.       bra      CAS1           branch to case 1 (not done) 
  199.  
  200.       endc 
  201.  
  202.  
  203. ***************     CASE 7:   LIT AND/OR REP DUMP & FINISH 
  204. CAS7 
  205.       move.l   PT,AM 
  206.       sub.l    IP,AM          AM = PT - IP (positive result > 0) 
  207. *                             if no literal run 
  208.       beq.s    C71               branch to replicate run 
  209.  
  210.       subq     #1,AM          AM = AM - 1 
  211.       move.b   AM,(OP)+       output literal control byte 
  212.  
  213. C70   move.b   (IP)+,(OP)+    output literal run 
  214.       dbra     AM,C70 
  215.  
  216. C71   move.l   PT,AM 
  217.       sub.l    IQ,AM          AM = PT - IQ (negative result) 
  218.       addq     #1,AM          AM = AM + 1 
  219.       move.b   AM,(OP)+       output replicate control byte 
  220.       move.b   CH,(OP)+       output repeated character 
  221.  
  222. *                             fall into case 8 
  223.  
  224.  
  225. ***************     CASE 8:   ADJUST PARAMS & RETURN VALUE 
  226. CAS8 
  227.       movea.l  FRM(FP),PT     PT = **from 
  228.       move.l   IQ,(PT)        *from = *from + amt 
  229.       movea.l  TOO(FP),PT     PT = **too 
  230.  
  231.       move.l   OP,RET
  232.       sub.l    (PT),RET       return = OP - *too
  233.  
  234.       move.l   OP,(PT)       *too = *too + return 
  235.       movem.l  (SP)+,REGS 
  236.       UNLK     FP 
  237.       rts
  238.  
  239.  
  240.  
  241.  
  242.  
  243.